package com.example.demo.chat_room;

import com.example.demo.chat_room.server.config.NettyAndWebSocketConfig;
import com.example.demo.chat_room.server.config.WebSocketStartConfig;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import jakarta.annotation.PreDestroy;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.LogManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Component;

/**
 * 这里是要连接前端来做通讯的
 * 可以理解为一个前后端集成demo
 */
@Component
public class NettyServerStart implements Runnable{

    // 用类创建会使类名作为这个日志记录器的名字,而用xml种定义过的reviewLog则会触发对应的配置内容
    // private static final Logger logger= LoggerFactory.getLogger(NettyServerStart.class);
    private static final Logger logger= LoggerFactory.getLogger("reviewLog");

    @Autowired
    // mongodb操作对象
    MongoTemplate mongoTemplate;

    // yml配置参数类
    @Autowired
    NettyAndWebSocketConfig nWConfig;

    // websocket启动配置类
    @Autowired
    WebSocketStartConfig webSocketStartConfig;

    private final EventLoopGroup bossGroup = new NioEventLoopGroup(1);
    private final EventLoopGroup workGroup = new NioEventLoopGroup(10);

    // PreDestroy注解在容器销毁时调用,关闭资源
    @PreDestroy
    public void close() {
        bossGroup.shutdownGracefully();
        workGroup.shutdownGracefully();
    }

    @Override
    public void run() {
        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();

            serverBootstrap.group(bossGroup,workGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, nWConfig.getChannelOptionBacklog())
                    // 将websocket启动配置通过注入放进来
                    .childHandler(webSocketStartConfig);

            ChannelFuture future = serverBootstrap.bind(nWConfig.getPort()).sync();
            System.out.println("服务器启动！");
            logger.info("启动！");
            future.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            bossGroup.shutdownGracefully();
            workGroup.shutdownGracefully();
        }
    }
}
